#include "utils_system.h"
#include "utils_log.h"
#include <array>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <signal.h>
#include <cstring>
#include <ctime>

namespace El {
namespace Utils {

bool IsSystemBigEndian() {
    unsigned int i = 1;
    char *c = (char*)&i;
    if (*c) {
        // Little-endian
        return false;
    } else {
        // Big-endian
        return true;
    }
}

bool ExecuteCommand(const std::string &cmd, std::string *output, int timeoutSeconds)
{
    if (cmd.empty()) {
        return false;
    }

    int pipefd[2];
    if (pipe(pipefd) == -1) {
        EL_ERROR("Failed to create pipe: {}", strerror(errno));
        return false;
    }

    pid_t pid = fork();
    if (pid == -1) {
        EL_ERROR("Failed to fork process: {}", strerror(errno));
        close(pipefd[0]);
        close(pipefd[1]);
        return false;
    }

    if (pid == 0) {
        // 子进程：执行命令
        close(pipefd[0]);
        dup2(pipefd[1], STDOUT_FILENO);
        dup2(pipefd[1], STDERR_FILENO);
        close(pipefd[1]);

        // 执行命令
        execl("/bin/sh", "sh", "-c", cmd.c_str(), nullptr);
        exit(127);
    }

    // 父进程：读取输出和处理超时
    close(pipefd[1]);

    // 设置非阻塞读取
    int flags = fcntl(pipefd[0], F_GETFL, 0);
    fcntl(pipefd[0], F_SETFL, flags | O_NONBLOCK);

    std::string result;
    std::array<char, 4096> buffer{};
    time_t startTime = time(nullptr);
    bool timeoutOccurred = false;

    while (true) {
        // 检查超时
        if (timeoutSeconds > 0 && (time(nullptr) - startTime) >= timeoutSeconds) {
            EL_WARN("Command execution timeout after {} seconds: {}", timeoutSeconds, cmd);
            kill(pid, SIGTERM);
            usleep(100000);  // 等待100ms
            kill(pid, SIGKILL);
            timeoutOccurred = true;
            break;
        }

        // 尝试读取数据
        ssize_t bytesRead = read(pipefd[0], buffer.data(), buffer.size() - 1);
        if (bytesRead > 0) {
            buffer[bytesRead] = '\0';
            result += buffer.data();
        } else if (bytesRead == 0) {
            // EOF，子进程结束
            break;
        } else if (errno != EAGAIN && errno != EWOULDBLOCK) {
            EL_ERROR("Failed to read from pipe: {}", strerror(errno));
            break;
        }

        usleep(10000);  // 等待10ms
    }

    close(pipefd[0]);

    // 等待子进程结束
    int status;
    int waitResult = waitpid(pid, &status, WNOHANG);
    if (waitResult == 0 && timeoutOccurred) {
        // 子进程还在运行，强制杀死
        kill(pid, SIGKILL);
        waitpid(pid, &status, 0);
    }

    if (output) {
        *output = result;
    }

    if (timeoutOccurred) {
        return false;
    }

    return waitResult > 0 && WIFEXITED(status) && WEXITSTATUS(status) == 0;
}

} // namespace Utils
} // namespace El
